package com.alibaba.citrus.ots.sales.plan.repository;

import com.alibaba.citrus.ots.common.annotation.RepositoryInvoker;
import com.alibaba.citrus.ots.common.exception.RepositoryException;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanReportRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanReportPageQueryRequest;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanReportSDO;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.SalesPlanReportLoadListRequest;
import com.epoch.app.bcots.sales_plan.salesplanreport.dto.CreateSalesPlanReportResponse;
import com.epoch.app.bcots.sales_plan.salesplanreport.dto.LoadSalesPlanReportRequest;
import com.epoch.app.bcots.sales_plan.salesplanreport.dto.UpdateSalesPlanReportResponse;
import com.epoch.app.bcots.sales_plan.salesplanreport.model.SalesPlanReport;
import com.epoch.app.bcots.sales_plan.salesplanreport.service.SalesPlanReportService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
public class SalesPlanReportRepositoryImpl implements SalesPlanReportRepository {

    @Resource
    private SalesPlanReportService salesPlanReportService;

    @Override
    @RepositoryInvoker(printLog = true)
    public String save(SalesPlanReportSDO salesPlanReportSDO) {
        SalesPlanReport salesPlanReport = new SalesPlanReport();
        BeanUtils.copyProperties(salesPlanReportSDO, salesPlanReport);
        salesPlanReport.setPlanId(Long.valueOf(salesPlanReportSDO.getPlanId()));
        salesPlanReport.setParentId(Optional.ofNullable(salesPlanReportSDO.getParentId()).map(Long::parseLong).orElse(null));
        salesPlanReport.setModelId(Long.valueOf(salesPlanReportSDO.getModelId()));
        salesPlanReport.setCreatorId(salesPlanReportSDO.getReportEmployeeId());
        salesPlanReport.setModifierId(salesPlanReportSDO.getReportEmployeeId());
        salesPlanReport.setTenantId("tny");
        salesPlanReport.setGmtCreate(new Date());
        salesPlanReport.setVersion(0L);
        CreateSalesPlanReportResponse salesPlanReportResponse = salesPlanReportService.createSalesPlanReport(salesPlanReport);
        return salesPlanReportResponse.getLastInsertId();
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public Boolean edit(SalesPlanReportSDO salesPlanReportSDO) {
        SalesPlanReport salesPlanReport = new SalesPlanReport();
        BeanUtils.copyProperties(salesPlanReportSDO, salesPlanReport);
        salesPlanReport.setParentId(Optional.ofNullable(salesPlanReportSDO.getParentId()).map(Long::parseLong).orElse(null));
        salesPlanReport.setId(Long.valueOf(salesPlanReportSDO.getId()));
        salesPlanReport.setGmtModified(new Date());
        salesPlanReport.setModifierId(salesPlanReportSDO.getReportEmployeeId());
        UpdateSalesPlanReportResponse updateSalesPlanReportResponse = salesPlanReportService.updateSalesPlanReport(salesPlanReport);
        return updateSalesPlanReportResponse.getCount() > 0;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<SalesPlanReportSDO> querySalesPlanReportList(QuerySalesPlanReportRequest querySalesPlanReportRequest) {
        SalesPlanReportLoadListRequest salesPlanReportLoadListRequest = new SalesPlanReportLoadListRequest();
        salesPlanReportLoadListRequest.setPlanId(Optional.ofNullable(querySalesPlanReportRequest.getPlanId()).map(Long::parseLong).orElse(null));
        salesPlanReportLoadListRequest.setBizType(querySalesPlanReportRequest.getBizType());
        salesPlanReportLoadListRequest.setBizId(querySalesPlanReportRequest.getBizId());
        salesPlanReportLoadListRequest.setModel(querySalesPlanReportRequest.getModel());
        salesPlanReportLoadListRequest.setReportEmployeeId(querySalesPlanReportRequest.getReportEmployeeId());
        salesPlanReportLoadListRequest.setModelId(Optional.ofNullable(querySalesPlanReportRequest.getModelId()).map(Long::valueOf).orElse(null));
        salesPlanReportLoadListRequest.setParentId(Optional.ofNullable(querySalesPlanReportRequest.getParentId()).map(Long::parseLong).orElse(null));
        salesPlanReportLoadListRequest.setStart(0);
        salesPlanReportLoadListRequest.setLimit(300);
        Result<List<SalesPlanReport>> listResult = salesPlanReportService.loadSalesPlanReportList(salesPlanReportLoadListRequest);
        List<SalesPlanReport> result = listResult.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return Collections.emptyList();
        }
        return result.stream().map(this::convertSalesPlanReportSDO).collect(Collectors.toList());
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public SalesPlanReportSDO load(QuerySalesPlanReportRequest querySalesPlanReportRequest) {
        LoadSalesPlanReportRequest loadSalesPlanReportRequest = new LoadSalesPlanReportRequest();
        loadSalesPlanReportRequest.setId(Long.parseLong(querySalesPlanReportRequest.getId()));
        SalesPlanReport salesPlanReport = salesPlanReportService.loadSalesPlanReport(loadSalesPlanReportRequest);
        return convertSalesPlanReportSDO(salesPlanReport);
    }

    /**
     * 分页查询提报单
     *
     * @param request
     * @return
     */
    @Override
    @RepositoryInvoker(printLog = true)
    public PageResult<List<SalesPlanReportSDO>> pageQuery(SalesPlanReportPageQueryRequest request) {
        SalesPlanReportLoadListRequest loadListRequest = convertSalesPlanReportLoadListRequest(request);
        try {
            Result<List<SalesPlanReport>> listResult = salesPlanReportService.loadSalesPlanReportList(loadListRequest);
            List<SalesPlanReport> result = listResult.getResult();
            List<SalesPlanReportSDO> salesPlanReportSDOList = result.stream().map(this::convertSalesPlanReportSDO).collect(Collectors.toList());
            return PageResult.of(salesPlanReportSDOList, listResult.getTotal());
        } catch (Exception e){
            throw new RepositoryException(ErrorMessage.code(""));
        }
    }

    private SalesPlanReportSDO convertSalesPlanReportSDO(SalesPlanReport source) {
        if (null == source) {
            return null;
        }
        SalesPlanReportSDO target = new SalesPlanReportSDO();
        target.setId(String.valueOf(source.getId()));
        target.setPlanId(String.valueOf(source.getPlanId()));
        target.setReportEmployeeId(source.getReportEmployeeId());
        target.setBizType(source.getBizType());
        target.setBizId(source.getBizId());
        target.setModel(source.getModel());
        target.setModelId(String.valueOf(source.getModelId()));
        target.setParentId(Optional.ofNullable(source.getParentId()).map(String::valueOf).orElse(null));
        target.setIsLeafTask(source.getIsLeafTask());
        target.setStatus(source.getStatus());
        target.setAuditStatus(source.getAuditStatus());
        target.setFeatures(source.getFeatures());
        target.setCreatorId(source.getCreatorId());
        target.setModifierId(source.getModifierId());
        target.setGmtCreate(source.getGmtCreate());
        target.setGmtModified(source.getGmtModified());
        return target;
    }

    private SalesPlanReportLoadListRequest convertSalesPlanReportLoadListRequest(SalesPlanReportPageQueryRequest source) {
        if (null == source) {
            return null;
        }
        SalesPlanReportLoadListRequest target = new SalesPlanReportLoadListRequest();
        target.setPlanId(Optional.ofNullable(source.getPlanId()).map(Long::parseLong).orElse(null));
        target.setBizType(source.getBizType());
        target.setBizId(source.getBizId());
        target.setModel(source.getModelType());
        target.setModelId(Optional.ofNullable(source.getModelId()).map(Long::parseLong).orElse(null));
        target.setStart(source.getStart());
        target.setLimit(source.getLimit());
        target.setReportEmployeeId(source.getReportEmployeeId());
        target.setParentId(Optional.ofNullable(source.getParentId()).map(Long::parseLong).orElse(null));
        target.setAuditStatus(source.getAuditStatus());
        target.setReportIdList(source.getReportIdList());
        return target;
    }
}
